
import 'package:dio/dio.dart';
import 'package:dio_log/interceptor/dio_log_interceptor.dart';
import 'package:flutter/foundation.dart';

import '../dio/dio_conf.dart';
import '../utils/logger_util.dart';
import '../utils/toast.dart';
import 'dio_log.dart';
import 'dio_setting.dart';

/// todo：dio网络请求
class DioUtil {
  static Dio dio;

  static DioUtil get instance => _getInstance();
  static DioUtil _instance;

  factory DioUtil() => _getInstance();

  static DioUtil _getInstance() {
    if (_instance == null) {
      _instance = new DioUtil._internal();
    }
    return _instance;
  }

  /// todo：DIO初始化
  DioUtil._internal() {
    if (dio == null) {
      BaseOptions options = BaseOptions();
      // 注册请求服务器
      options.baseUrl = DioConf.baseUrl;
      // 设置连接超时单位毫秒
      options.connectTimeout = DioConf.connectTimeout;
      // 设置接收超时时间
      options.receiveTimeout = DioConf.receiveTimeout;
      // 设置请求超时单位毫秒
      options.sendTimeout = 5000;
      // 设置返回类型
      options.responseType = ResponseType.json;
      // 设置请求头
      options.headers = DioConf.headers;
      // 实例化Dio
      dio = Dio(options);
      // 添加拦截器
      dio.interceptors.add(DioSetting.interceptorsWrapper);
      // 开启自定义请求日志：LogInterceptorUtil
      // kDebugMode = debug模式
      dio.interceptors.add(
        DioLogInterceptor()
        // LogInterceptorUtil(
        //   responseBody: kDebugMode,
        // ),
      );
    }
  }

  /// todo：post请求
   Future<Response> post({
    String path,
    dynamic data,
    Map<String, dynamic> queryParameters,
    Options options,
    CancelToken cancelToken,
    ProgressCallback onSendProgress,
    ProgressCallback onReceiveProgress,
  }) async => await _request(path,data:data,type:"post",queryParameters:queryParameters,options:options,cancelToken:cancelToken,onSendProgress:onSendProgress,onReceiveProgress:onReceiveProgress);

  /// todo：get请求
   Future<Response> get({
    String path,
    Map<String, dynamic> queryParameters,
    Options options,
    CancelToken cancelToken,
    ProgressCallback onReceiveProgress,
  }) async => await _request(path,type:"get",queryParameters:queryParameters,options:options,cancelToken:cancelToken,onReceiveProgress:onReceiveProgress);

  /// todo：del请求
  Future<Response> delete({
    String path,
    dynamic data,
    Map<String, dynamic> queryParameters,
    Options options,
    CancelToken cancelToken,
  }) async => await _request(path,data:data,type:"del",queryParameters:queryParameters,options:options,cancelToken:cancelToken);

  /// todo：pub请求
   Future<Response> put({
    String path,
    dynamic data,
    Map<String, dynamic> queryParameters,
    Options options,
    CancelToken cancelToken,
    ProgressCallback onSendProgress,
    ProgressCallback onReceiveProgress,
  }) async => await _request(path,data:data,type:"put",queryParameters:queryParameters,options:options,cancelToken:cancelToken,onSendProgress:onSendProgress,onReceiveProgress:onReceiveProgress);

   Future<Response> _request(
    path,
  {dynamic data,
    Map<String, dynamic> queryParameters,
    Options options,
    CancelToken cancelToken,
    Function(int,int) onSendProgress,
    Function(int,int) onReceiveProgress,
    String type,
  }) async{

    Response response;

    if(type == "post"){
      response = await dio.post(path, data: data, queryParameters: queryParameters, onReceiveProgress: onReceiveProgress, onSendProgress: onSendProgress, options: options, cancelToken: cancelToken,).catchError((error)  {_log(error);});
    }

    if(type == "get"){
      response = await dio.get(path, queryParameters: queryParameters, onReceiveProgress: onReceiveProgress, options: options, cancelToken: cancelToken,).catchError((error) {_log(error);});
    }

    if(type == "del"){
      response = await dio.delete(path,data: data, queryParameters: queryParameters, options: options, cancelToken: cancelToken,).catchError((error) {_log(error);});
    }

    if(type == "put"){
      response = await dio.put(path, data: data, queryParameters: queryParameters, options: options, cancelToken: cancelToken, onSendProgress: onSendProgress, onReceiveProgress: onReceiveProgress,).catchError((error) {_log(error);});
    }

    if (response != null) {
      if (response.statusCode == 200 && response.data != null) {
        return response;
      } else {
        error("网络请求失败！${response.statusCode}");
        return null;
      }
    } else {
      return null;
    }
  }

   _log(error){
    logger(error, name: "dio异常");
    error("网络请求失败！");
  }
}
